﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ThreeByte.ActiveDeck.Config;
using ThreeByte.ActiveDeck.Content;
using log4net;
using System.ComponentModel;
using ThreeByte.ActiveDeck.AddIn.Config;

namespace ThreeByte.ActiveDeck.AddIn.Controls
{
    /// <summary>
    /// Interaction logic for PageConfigurationControl.xaml
    /// </summary>
    public partial class PageConfigurationControl : UserControl
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(PageConfigurationControl));

        public PageConfigurationControl() {
            InitializeComponent();

            //TODO: Deal with preventing this from design mode operation
            //if(!(DesignerProperties.GetIsInDesignMode(new DependencyObject()))) {
            //    throw new InvalidProgramException("This constructor should never be used.  Designer use only");
            //}

        }

        public PageConfigurationControl(PageConfig page) :this() {
            PageConfig = page;
            UpdateUIWithConfig(PageConfig);
        }

        //public void LoadConfigForSlide(PowerPoint.SlideRange slideRange) {

        //    CurrentSlideId = slideRange.SlideID;

        //    SlideNumberTextBlock.Text = string.Format("Slide Num: {0}", slideRange.SlideNumber);
        //    SlideNumberTextBlock.ToolTip = string.Format("ID {0}", slideRange.SlideID);

        //    if(Config.ContainsId(CurrentSlideId)) {
        //        TriggeriPadCheckBox.IsChecked = true;
        //        UpdateUIWithConfig(Config[CurrentSlideId]);
        //    } else {
        //        TriggeriPadCheckBox.IsChecked = false;
        //        UpdateUIWithConfig(null);
        //    }

        //    UpdateUserDataControls();
        //}

        //public PageConfig Config {
        //    get;
        //    private set;
        //}

//        private SlideConfig SlideConfig;
        public static readonly DependencyProperty PageConfigProperty = DependencyProperty.Register("PageConfig",
            typeof(PageConfig), typeof(PageConfigurationControl));

        public PageConfig PageConfig {
            get {
                return (PageConfig)GetValue(PageConfigProperty);
            }
            set {
                SetValue(PageConfigProperty, value);
            }
        }

        public event EventHandler<PageConfigUpdatedEventArgs> PageConfigUpdated;

        private void UpdateUIWithConfig(PageConfig config) {
            ConfigurationRoot.Children.Clear();
            PreviewRoot.Content = null;
            if(config == null) {
                return;
            }

            config.Refresh();
            //Look for layers and refresh if they haven't been
            if(config is DesignerSlideConfig) {
                foreach(LayerConfig l in ((DesignerSlideConfig)config).Layers) {
                    l.Refresh(false);
                }
            }
            if(config is NavigatorConfig) {
                foreach(LayerConfig l in ((NavigatorConfig)config).Layers) {
                    l.Refresh(false);
                }
            }

            //***** CONFIGURATION *****
            //Set the template comboBox
            uiSelectionEnabled = false;
            TemplateComboBox.SelectedValue = config.GetType();
            uiSelectionEnabled = true;

            try {
                string configurationTypeName = config.GetType().FullName;
                configurationTypeName = configurationTypeName.Replace(".Config.", ".Controls.");
                configurationTypeName = configurationTypeName.Replace("Config", "Configuration");

                //use reflection to instantiate a configuration user control
                Type configurationType = Type.GetType(configurationTypeName, true);
                UserControl configurationControl = (UserControl)configurationType
                                    .GetConstructor(new Type[] { config.GetType() })
                                    .Invoke(new object[] { config });

                //Then navigate to it
                ConfigurationRoot.Children.Add(configurationControl);
            } catch(Exception ex) {
                //If the configuration pane doesn't exist, don't freak out
                log.Warn("The configuration pane could not be loaded", ex);
            }

            //***** PREVIEW *****
            PreviewRoot.Content = PagePreviewFactory.Create(config);
        }

        private bool uiSelectionEnabled = true;
        private void TemplateComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
            if(uiSelectionEnabled) {
                CreateNewConfigByType((Type)(TemplateComboBox.SelectedValue));
            }
        }

        private void CreateNewConfigByType(Type configurationType) {
            if(ConfigurationRoot == null) {
                return;
            }

            PageConfig oldConfig = PageConfig;
            PageConfig = (PageConfig)configurationType
                    .GetConstructor(new Type[] { })
                    .Invoke(new object[] { });
            
            if(PageConfigUpdated != null) {
                PageConfigUpdated(this, new PageConfigUpdatedEventArgs(oldConfig, PageConfig));
            }
            //Config[PageIndex] = config;
            PageConfig.Refresh();

            UpdateUIWithConfig(PageConfig);
        }

        private void OrientationComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
            log.Debug("Orientation Changed");
        }


    }

    public class PageConfigUpdatedEventArgs : EventArgs
    {
        public PageConfig OldPageConfig;
        public PageConfig NewPageConfig;

        public PageConfigUpdatedEventArgs(PageConfig oldPage, PageConfig newPage) {
            OldPageConfig = oldPage;
            NewPageConfig = newPage;
        }

    }
}
